<template>
    <a-tree-select
        v-bind="$attrs"
        v-on="$listeners"
        tree-data-simple-mode
        allow-clear
        style="width: 100%"
        :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
        :tree-checkable="treeCheckable"
        :replaceFields="treeReplace"
        :tree-data="treeData"
        :load-data="isLazyLoad ? onLoadData : null"
        @treeExpand="handleTreeExpand"
        @select="handleSelect"
        @change="handleChange"
        ref="treeSelect"
    />
</template>

<script>
import { TreeSelect } from 'ant-design-vue'
import { getDepartmentList } from '@/api/businessAffairs/revenueAndCost'
import { getOneOrgUsers } from '@/api/commons.js'
const SHOW_ALL = TreeSelect.SHOW_ALL //显示所有选中节点(包括父节点)
const SHOW_PARENT = TreeSelect.SHOW_PARENT //只显示父节点(当父节点下所有子节点都选中时)
const SHOW_CHILD = TreeSelect.SHOW_CHILD //默认只显示子节点.
export default {
    name: 'orgStaffAsync',
    props: {
        /**
         * @description: 定义选中项回填的方式
         * @param {} SHOW_ALL  显示所有选中节点(包括父节点)
         * @param {} SHOW_PARENT  只显示父节点(当父节点下所有子节点都选中时)
         * @param {} SHOW_CHILD  默认只显示子节点
         */
        showCheckedStrategy: {
            default: SHOW_CHILD,
        },
        selectedValue: {
            type: [Array, String],
            default: () => [],
        },
        // 是否有复选框
        treeCheckable: {
            type: Boolean,
            default: true,
        },
        // 组织是否可选
        orgCheckable: {
            type: Boolean,
            default: false,
        },
        // 员工是否可选
        staffCheckable: {
            type: Boolean,
            default: true,
        },
        // 是否需要懒加载
        isLazyLoad: {
            type: Boolean,
            default: true,
        },
        // 是否需要单独加载绑定值的组织结构
        useSingle: {
            type: Boolean,
            default: false,
        },
        //多选情况下 组织是否可选
        disableCheckbox: {
            type: Boolean,
            default: false,
        },
        // 查询员工是是否查询是否为领导 '0' 否 | '1' 是 | '' 所有
        isLeader: {
          type: String,
          default: '',
        },
        // 需要联动的表单名，
        form: {
            type: Object,
            default: function () {
                return {}
            },
        },
        // 需要联动的表单名
        keyValue: {
            type: String,
            default: function () {
                return 'unitId'
            },
        },
        isObj: {
            type: Boolean,
            default() {
                return false
            },
        },
        // 员工可选情况下，是否可以选组织下所有员工
        checkableAllOrgStaff: {
          type: Boolean,
          default: false
        },
        // 是否只筛选部门，不需要项目部
        onlyDept: {
          type: Boolean,
          default: false
        }
    },
    data() {
        return {
            cachePreOrgList: [], // 缓存在useSingle模式下，已预加载过的组织结构，避免重复加载
            cachePreStaffList: [], // 缓存在useSingle模式下，已预加载过的人员，避免重复加载
            refreshLock: false,
            treeReplace: {
                title: 'name',
                value: 'id',
                key: 'id',
            },
            treeData: [],
        }
    },
    watch: {
        // 监听联动表单值重置项目列表
        attr(val) {
            // 重置列表
           this.treeData = []
            val && this.getOrgsTree()
            // val && this.getProjectInfo({ query: { branchComIds: [val] } })
        },
        selectedValue: {
            handler(val) {
                if (this.useSingle && val.length && !this.refreshLock) {
                    // 用于编辑页等回显时，确保selectedValue有获取到值，以完成后续优化流程，该行为只需调用一次，因此加上refreshLock标志
                    this.refreshLock = true
                    this.getOrgsTree()
                }
            },
        },
    },
    created() {
        let val = this.attr
        val && this.getOrgsTree()
    },
    computed:{
      // 需要联动的表单值
      attr() {
          if (this.isObj) {
              // this.form[this.keyValue]
              return this.form[this.keyValue]?.key
          } else {
              return this.form[this.keyValue]
          }
      },
    },
    methods: {
        getOriginRef() {
            return this.$refs.treeSelect
        },
        /**
         * @description: 组织树选择
         * @function {getOrgsTreeList} 请求组织列表
         * @function {parentTreeFun} 遍历组织数组列表，独立节点不展示checkable[boolean]
         */
        getOrgsTree() {
          let that = this
          let id = this.attr;
          let data = {
              id: id,
              type: '2',
          }
          getDepartmentList(data).then((res) => {
                if (res.status === 200) {
                    if (!that.useSingle) {
                      that.treeData = that.parentTreeFun(res.data)
                    } else {
                        // 使用useSingle模式时，对数据加载过程优化

                      that.treeData = res.data.map((item) => {
                            return {
                                ...item,
                                value: item.id,
                                label: item.name,
                                checkable: that.orgCheckable,
                                selectable: that.orgCheckable,
                            }
                        })
                        // 根据值是否为数组，填充不同的查询参数
                        const params = Array.isArray(that.selectedValue)
                            ? {
                                  ids: that.selectedValue,
                              }
                            : {
                                  id: that.selectedValue,
                              }
                        const flag = Array.isArray(that.selectedValue)
                            ? !!that.selectedValue.length
                            : !!that.selectedValue
                        // 有值时才查询该值对应的组织(orgId)
                        flag &&
                            getDepartmentList(params).then((res) => {
                                let arr =
                                    (res.data &&
                                        res.data.map((item) => {
                                            return (
                                                (item.posts &&
                                                    item.posts.map((items) => {
                                                        return items.orgId
                                                    })) ||
                                                []
                                            )
                                        })) ||
                                    []
                                arr = arr.flat()
                              that.cachePreOrgList = arr
                                arr.length &&
                                that.treeData.forEach((item, i) => {
                                        if (arr.includes(item.id)) {
                                            that.getStaffList(item.id)
                                        }
                                    })
                            })
                    }
                }
            })
        },
        // 获取组织下的人员列表
        getStaffList(id) {
            let param = {
              pageNumber: 1,
              pageSize: 1000,
              orgId: id
            }
            if (this.isLeader !== '') param.isLeader = this.isLeader;
            getOneOrgUsers(param).then((res) => {
                // 去重,避免加载重复的人员
                const list = res.data.filter((item) => {
                    if (this.cachePreStaffList.includes(item.id)) {
                        return false
                    } else {
                        this.cachePreStaffList.push(item.id)
                        return true
                    }
                })
                this.treeData = this.treeData.concat(
                    list.map((item) => {
                        return {
                            ...item,
                            checkable: this.staffCheckable,
                            selectable: this.staffCheckable,
                            pId: id,
                        }
                    })
                )
            })
        },
        parentTreeFun(data, staff) {
            return data.map((value, key, arr) => {
                return this.childrenTreeFun(value, staff)
            })
        },      
        childrenTreeFun(value, staff) {
            value.checkable = this.orgCheckable
            value.selectable = this.orgCheckable
            value.disableCheckbox = this.disableCheckbox
            if (value.children) {
               
                this.parentTreeFun(value.children)
            } else {
                !this.isLazyLoad &&
                    this.onLoadData({
                        // 不需要懒加载时，请求所有人员信息
                        dataRef: {
                            id: value.id,
                            node: value
                        },
                    })
            }
            return value
        },
        /**
         * @description: 异步加载树节点—人员
         * @param {orgId} 如果为空，请求全部人员
         */
        onLoadData(treeNode) {
            const _this = this
            return new Promise((resolve) => {
                const { id, node } = treeNode.dataRef
                if (this.cachePreOrgList.includes(id)) {
                    // 避免请求重复的人员数据
                    resolve()
                    return
                }
                const param = {
                  pageNumber: 1,
                  pageSize: 1000,
                  orgId: id
                }
                if (this.isLeader !== '') {
                  param.isLeader = Number(this.isLeader);
                }
                getOneOrgUsers(param).then((res) => {
                    if (res && res.data && res.data.list.length) {
                        const list = res.data.list.filter((item) => {
                            if (this.cachePreStaffList.includes(item.id)) {
                                return false
                            } else {
                                this.cachePreStaffList.push(item.id)
                                return true
                            }
                        })
                        // const data = res.data
                        // data.forEach((value, key, arr) => {
                        list.forEach((value, key, arr) => {
                            if (_this.staffCheckable === false) {
                                value.checkable = false
                                value.selectable = false
                            }
                            value.pId = id // 避免不同orgId查询到的数据里，pId一致的问题
                        })
                        setTimeout(() => {
                            if (list.length && this.checkableAllOrgStaff && this.staffCheckable) {
                              node.checkable = this.checkableAllOrgStaff
                              node.selectable = this.checkableAllOrgStaff
                            }
                            this.treeData = this.treeData.concat(list)
                            resolve()
                        }, 200)
                    }
                })
            })
        },
        /**
         * @description: 展开节点时调用
         * @param {object} expandedKeys 展开节点时的对象
         */
        handleTreeExpand(expandedKeys) {
            this.$emit('update:expandedKeys', expandedKeys)
            // this.$emit('handleExpanded', expandedKeys)
        },
        /**
         * @description: 被选中时调用
         * @param {string} value 被选中时调用的id字符串
         */
        handleSelect(value, node, extra) {
            this.$emit('update:selectValue', value)
            // this.$emit('handleSelect', value)
        },
        /**
         * @description: 选中树节点时调用此函数
         * @param {object} value  选中树节点的id对象
         * @param {object} label  选择树节点的文本信息对象
         */
        handleChange(value, label, extra) {
            this.$emit('update:selectedValue', value)
            this.$emit('update:selectedLable', label)
            if (this.$listeners['selectedObj']) {
              this.$emit('selectedObj', this.getSelectedObj(extra.allCheckedNodes))
            }
            // this.$emit('handleChange', extra.triggerNode.dataRef)
        },
        getSelectedObj(nodeObj) {
          const result = [];
          if (!nodeObj) return result;
          nodeObj.map((value, key) => {
            if (value.children) {
              value.children.map((item, idx) => {
                const data = item.node?.data || item.data;
                if (!data.props.type) {
                  result.push(data.props.dataRef)
                }
              })
            } else {
              const data = value.node?.data || value.data
              if (!data.props.type) {
                result.push(data.props.dataRef)
              }
            }
          })
          return result
        }
    },
}
</script>
<style>
    /deep/ .ant-select-tree li span.ant-select-tree-switcher,
    .ant-select-tree li span.ant-select-tree-iconEle{
        line-height: 12px !important;
    }
</style>